// bzoj2227
// 题意：
//   有一个电影院，k(≤200) 个座位排成一排。现在 n(≤200) 个人，按序进入，
//   每个人会拿到一张票， 票会等概率的抽到一个座位L，如果L有人就将L加一，
//   直到第一个没人的位置，如果一直到最右边都还有人，那么就站着。
//   问 n 个人都有座的概率。
//
// 题解：
//   很不错的组合数学题，构造很巧秒。首先，如果当n>k时概率为零。然后，
//   所有可能的方案数是 k^n。我们这样考虑，在第k号位后面加个空座，
//   再将他们首尾相接弄成一个环， 然后按照原来的方法就坐。
//   n个人都有座等价于加入的k+1号座没人。
//   那么我们先看 k+1 个座位构成的环，共有 (k+1)^n 种情况，
//   然后要将它还原成链并且 k+1 号为空。做了 n 个人，剩余 k+1−n个座，
//   都有可能是 k+1 号座，所以再乘以 k+1−n，注意到是个圆上排列，有重复，
//   要再除以 k+1。都有座的方案数就是 (k+1)^(n−1) * (k+1−n)种。
//
// 统计：128ms, 40min, 4wa
//
// run: $exec < input
#include <iostream>
#include <cstring>

int n, k;

int gcd(int x, int y)
{
	return (!y ? x : gcd(y, x % y));
}

void print(int x, int y, long long init)
{
	long long a[3000];
	std::memset(a, 0, sizeof(a));
	a[0] = init;
	int l = 1;
	for (int i = 0; i < y; i++) {
		for (int j = 0; j < l; j++) a[j] *= x;
		for (int j = 0; j < l; j++) {
			if (a[j] < 10) continue;
			a[j + 1] += a[j] / 10;
			a[j] %= 10;
			if (j == l - 1) l++;
		}
	}
	for (int i = l - 1; i >= 0; i--)
		std::cout << a[i];
}

int main()
{
	int T; std::cin >> T;
	while (T--) {
		std::cin >> n >> k;
		if (n > k) std::cout << "0 1\n";
		else {
			int t = n, t1 = k + 1 - n;
			long long init = 1;
			for (int i; (i = gcd(t1, k)) != 1 && t; t1 /= i, t--)
				init *= k / i;

			print(k + 1, n - 1, t1);
			std::cout << " ";
			print(k, t, init);
			std::cout << '\n';
		}
	}
}

